﻿package bdz.common.graphics {
	
import flash.display.BitmapData;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.display.Sprite;
import flash.utils.clearInterval;
import flash.utils.setInterval;
import flash.utils.getTimer;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.Shape;


	public class MarchingAntsRect extends MovieClip{
		
		private var patternLength:Number;
		private var colors:Array;
		private var pattern:Array;
		private var patternMap:BitmapData;
		private var copyRect:Rectangle;
		private static var copyPoint:Point = new Point(1, 0);
		private var updateID:Number;
		private var lastUpdate:Number;
		private var rect:Rectangle;
		
		public function MarchingAntsRect(colors:Array, pattern:Array) {
			rect = new Rectangle();
			setPattern(colors, pattern);
		}
		public function setPattern(colors:Array, pattern:Array):void {
			if (this.colors == null) {
				this.colors = [0xff000000, 0xffffffff];
			} else {
				this.colors = this.colors.slice();
			}
			if (pattern == null || pattern.length != this.colors.length) {
				this.pattern = [2, 2];
			} else {
				this.pattern = pattern.slice();
			}
			initBitmap();
		}
		public function draw(canvas:MovieClip, rect:Rectangle, speed:int, steps:int):void {
			paint(canvas, rect);
			if (speed != 0 && speed<10) {
				speed = 10;
			}
			
			steps = ((steps%patternLength)+patternLength)%patternLength;
			clearInterval(updateID);
			if (speed != 0) {
				updateID = setInterval(update, speed, steps);
			}
			if (getTimer()-lastUpdate>speed) {
				update(steps);
			}
		}
		public function clear():void {
			
			clearInterval(updateID);
		}
		private function paint(canvas:MovieClip, r:Rectangle):void {
			rect = new Rectangle(r.width < 0 ? r.x + r.width : r.x, r.height < 0 ? r.y + r.height : r.y, Math.abs(r.width), Math.abs(r.height));
			canvas.graphics.clear();
			canvas.graphics.lineStyle();
			canvas.graphics.moveTo(rect.left, rect.top);
			canvas.graphics.beginBitmapFill(patternMap, new Matrix(1, 0, 0, 1, rect.left%patternLength, 0));
			canvas.graphics.lineTo(rect.left+rect.width, rect.top);
			canvas.graphics.lineTo(rect.left+rect.width, rect.top+1);
			canvas.graphics.lineTo(rect.left, rect.top+1);
			canvas.graphics.lineTo(rect.left, rect.top);
			canvas.graphics.endFill();
			
			canvas.graphics.moveTo(rect.left+rect.width, rect.top+1);
			canvas.graphics.beginBitmapFill(patternMap, new Matrix(0, 1, 1, 0, 0, 1+rect.top%patternLength+patternLength-rect.width%patternLength));
			canvas.graphics.lineTo(rect.left+rect.width, rect.top+rect.height);
			canvas.graphics.lineTo(rect.left+rect.width-1, rect.top+rect.height);
			canvas.graphics.lineTo(rect.left+rect.width-1, rect.top+1);
			canvas.graphics.lineTo(rect.left+rect.width, rect.top+1);
			canvas.graphics.endFill();
			canvas.graphics.moveTo(rect.left, rect.top+rect.height-1);
			canvas.graphics.beginBitmapFill(patternMap, new Matrix(-1, 0, 0, 1, rect.left+rect.width-1-(patternLength-(rect.width+rect.height-1)%patternLength), 0));
			canvas.graphics.lineTo(rect.left+rect.width-1, rect.top+rect.height-1);
			canvas.graphics.lineTo(rect.left+rect.width-1, rect.top+rect.height);
			canvas.graphics.lineTo(rect.left, rect.top+rect.height);
			canvas.graphics.lineTo(rect.left, rect.top+rect.height-1);
			canvas.graphics.endFill();
			canvas.graphics.moveTo(rect.left, rect.top+1);
			canvas.graphics.beginBitmapFill(patternMap, new Matrix(0, -1, 1, 0, 0, 1+rect.top%patternLength));
			canvas.graphics.lineTo(rect.left+1, rect.top+1);
			canvas.graphics.lineTo(rect.left+1, rect.top+rect.height-1);
			canvas.graphics.lineTo(rect.left, rect.top+rect.height-1);
			canvas.graphics.lineTo(rect.left, rect.top+1);
			canvas.graphics.endFill();
		}
		private function update(steps:Number):void {
			do {
				var p:Number = patternMap.getPixel32(patternMap.width-1, 0);
				patternMap.copyPixels(patternMap, copyRect, copyPoint);
				patternMap.setPixel32(0, 0, p);
			} while (--steps>0);
			lastUpdate = getTimer();
		}
		private function initBitmap():void {
			patternLength = 0;
			var i:Number;
			for (i = 0; i<pattern.length; i++) {
				patternLength += pattern[i];
			}
			patternMap = new BitmapData(patternLength, 1, true, 0);
			var x:Number = 0;
			for (var k:Number = 0; k<pattern.length; k++) {
				for (var j:int = 0; j<pattern[k]; j++) {
					patternMap.setPixel32(x++, 0, colors[k]);
				}
			}
			copyRect = new Rectangle(0, 0, patternLength-1, 1);
		}
		public function get croppedArea():Rectangle {
			if(rect.width>1 && rect.height > 1){
				return rect;
			}
			return null;
		}
	}
}

